package day14;

import java.util.concurrent.TimeUnit;

/**
 * @author: 王丹
 * @create: 2021-07-06 14:25
 **/
//唤醒方法在等待方法之前执行，线程能够被唤醒么？
public class Demo3 {
    static Object lock = new Object();

    /**
     * 运行结果分析：
     * 输出了上面2行之后，程序一直无法结束，t1线程调用wait()方法之后无法被唤醒了，从输出中可见，
     * notify()方法在 wait()方法之前执行了，等待的线程无法被唤醒了。说明：唤醒方法在等待方法之前执行，
     * 线程无法被唤醒。
     */
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (lock) {
                System.out.println(System.currentTimeMillis() + "," + Thread.currentThread().getName() + " start!");
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(System.currentTimeMillis() + "," + Thread.currentThread().getName() + " 被唤醒!");
            }
        });
        t1.setName("t1");
        t1.start();
        //休眠1秒后唤醒lock对象上等待的线程
        TimeUnit.SECONDS.sleep(1L);
        //注意必须使用synchronized获取对象监视器，否则抛出java.lang.IllegalMonitorStateException异常
        //抛出该异常表明某一线程已经试图等待对象的监视器，或者试图通知其他正在等待对象的监视器，
        //然而本身没有指定的监视器的线程。
        synchronized (lock) {
            lock.notify();
        }
        System.out.println("lock.notify() 执行完毕");
    }
}
